﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq.Expressions;
using Loki.Utils;

namespace Loki.UI.Win
{
    public class NotifyPropertyChangingWrapper<T> : INotifyPropertyChanging
    {
        private static Dictionary<string, PropertyChangingEventArgs> _EventArgs = new Dictionary<string, PropertyChangingEventArgs>();
        private static object _lock = new object();

        private string _PropertyName;
        public NotifyPropertyChangingWrapper(Expression<Func<T, object>> P_Property)
        {
            _PropertyName = ExpressionHelper.GetProperty(P_Property).Name;
            lock (_lock)
            {
                if (!_EventArgs.ContainsKey(_PropertyName))
                {
                    _EventArgs[_PropertyName] = ObservableHelper.CreateChangingArgs(P_Property);
                }
            }
        }

        #region Event
        private readonly object PropertyChangingEventLock = new object();
        private PropertyChangingEventHandler PropertyChangingEvent;

        /// <summary>
        /// Event raised after the <see cref="Text" /> property value has changed.
        /// </summary>
        public event PropertyChangingEventHandler PropertyChanging
        {
            add
            {
                lock (PropertyChangingEventLock)
                {
                    PropertyChangingEvent += value;
                }
            }
            remove
            {
                lock (PropertyChangingEventLock)
                {
                    PropertyChangingEvent -= value;
                }
            }
        }

        /// <summary>
        /// Raises the <see cref="PropertyChanging" /> event.
        /// </summary>
        /// <param name="e"><see cref="PropertyChangingEventArgs" /> object that provides the arguments for the event.</param>
        protected virtual void OnPropertyChanging(PropertyChangingEventArgs e)
        {
            PropertyChangingEventHandler handler = null;

            lock (PropertyChangingEventLock)
            {
                handler = PropertyChangingEvent;

                if (handler == null)
                    return;
            }

            handler(this, e);
        }
        #endregion

        public void EventBridge(object sender, EventArgs e)
        {
            OnPropertyChanging(_EventArgs[_PropertyName]);
        }

    }
}
